home *** CD-ROM | disk | FTP | other *** search
- /* implements a nonlinear transfer function using Chebyshev polynomials of user-specified order. */
-
- #include "plugin_specific.h"
- #include "aiff.h"
- #include "num_input_macros.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <limits.h>
-
- #define MAXORDER 16 /* MAX. ORDER of chebyshev polynomial */
- #define CILOG2 11 /* see below */
- #define CHECK_INC ( 1U << CILOG2 ) /* period of progress report, */
- /* in table entries */
- static short *xferfunc;
-
- void init_process_chebyshev( void ) {
- short i, t, *txferfunc, order;
- double twox, *tp;
- double p[MAXORDER] = {1};
-
- if ( (nh.wdsi < 9) || (nh.wdsi > 16) )
- err( "Cannot process a file with this word size" );
-
- if ( USHRT_MAX != 65535 )
- err( "this plugin is based on the assumption of 2 byte shorts" );
-
- if (!(xferfunc = malloc( 0x20000 )))
- err( "Couldn't allocate transfer function table memory" );
-
- GET_NUM_RANGE( "order", "%hd", "%hd", order, 1, MAXORDER );
-
- fputs( "Generating transfer function table...\n" , stderr);
- for (i=0; i < 0x10000 / CHECK_INC; i++) fputc( '*', stderr );
- fputc( '\n', stderr );
-
- txferfunc = xferfunc;
- i = -0x8000;
- do {
- if ((i % CHECK_INC) == 0) /* progress report time */
- fputc( '*', stderr );
-
- tp = &p[1];
- *tp = (double) i / 0x8000;
- twox = *tp * 2;
-
- for ( t=2; t<=order; t++ ) {
- tp++;
- *tp = *(tp-1) * twox - *(tp-2);
- }
-
- *txferfunc++ = *tp * 0x7FFE; /* 1 */
- } while ( i++ < 0x7FFF);
-
- fputs( "\n\n", stderr );
- }
- /* 1. assumes |*tp|/1 <= 0x7FFF/0x7FFE */
-
- void term_process_chebyshev ( void ) {
- free( xferfunc );
- }
-
- void process_samdat_chebyshev ( long buflen ) {
- register short *td, *endd, *txferfunc;
-
- td = d;
- txferfunc = xferfunc;
- endd = &td[nh.chan * buflen];
-
- do {
- *td++ = txferfunc[ 0x8000 + *td ];
- } while ( td < endd );
- }
- plugin_info plugin_chebyshev = {
- init_process_chebyshev,
- term_process_chebyshev,
- process_samdat_chebyshev,
- 1, /* take_input */
- 1 /* make_output */
- };
-